﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using BCAMap.AMap.Dto;
using BCAMap.AMap.Http;
using BCAMap.Dto;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace BCAMap.AMap
{
    public class AMapUtils : IAMapUtils
    {
        public AMapUtils()
        {
        }

        public DistanceResponseDto GetDistance(DistanceRequestDto distanceRequestDto)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            string url = string.Format("{0}?key={1}&origins={2}&destination={3}&type={4}",
                AMapWebApiConfig.DistanceUrl,
                distanceRequestDto.Key,
                string.Join("|", distanceRequestDto.Origins.Select(p => string.Join(",", p))),
                string.Join(",", distanceRequestDto.Destination),
                distanceRequestDto.Type.HasValue ? (int)distanceRequestDto.Type : 1);

            HttpRequestDto httpRequestDto = new HttpRequestDto()
            {
                Headers = headers,
                Url = url,
                Method = MethodType.GET,
                ContentType = FormatType.JSON,
                Encoding = Encoding.UTF8.ToString()
            };
            HttpHandle http = new HttpHandle();
            HttpResponseDto response = http.HttpSendRequest(httpRequestDto);

            return JsonConvert.DeserializeObject<DistanceResponseDto>(response.ResponseMessage,
                new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new SnakeCaseNamingStrategy
                        {
                            ProcessDictionaryKeys = false
                        }
                    }
                });

        }

        public LocationResponseDto GetLocation(LocationRequestDto locationRequestDto)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            string url = string.Format("{0}?key={1}&location={2}&extensions=base",
                AMapWebApiConfig.LocationUrl,
                locationRequestDto.Key,
                locationRequestDto.location
                );

            HttpRequestDto httpRequestDto = new HttpRequestDto()
            {
                Headers = headers,
                Url = url,
                Method = MethodType.GET,
                ContentType = FormatType.JSON,
                Encoding = Encoding.UTF8.ToString()
            };
            HttpHandle http = new HttpHandle();
            HttpResponseDto response = http.HttpSendRequest(httpRequestDto);
            string message = response.ResponseMessage;
            Regex regex = new Regex("[A-Z]");

            while (regex.IsMatch(message))
            {
                string value = regex.Match(message).Value;
                message = message.Replace(value, "_" + value.ToLower());
            }

            var fuckAmap = JsonConvert.DeserializeObject<dynamic>(message);

            if (fuckAmap.status?.ToString() == "0")
            {
                throw new ArgumentException("查询地图 API 出错，可能是你提供的位置信息不正确，请打开定位服务，并稍后再试。");
            }

            if (fuckAmap.regeocode?.formatted_address?.ToString() == "[]")
            {
                throw new ArgumentException("查询地图 API 出错，可能是你提供的位置信息不正确，请打开定位服务，并稍后再试。");
            }

            return JsonConvert.DeserializeObject<LocationResponseDto>(message, new JsonSerializerSettings
            {
                ContractResolver = new DefaultContractResolver
                {
                    NamingStrategy = new SnakeCaseNamingStrategy { ProcessDictionaryKeys = false }
                }
            });
        }

        public GeographyResponseDto GetGeography(GeographyRequestDto geographyRequestDto)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            string url = string.Format("{0}?key={1}&keywords={2}&subdistrict={3}&extensions=base",
                AMapWebApiConfig.GeographUrl,
                geographyRequestDto.Key,
                geographyRequestDto.keywords,
                geographyRequestDto.subdistrict
                );

            HttpRequestDto httpRequestDto = new HttpRequestDto()
            {
                Headers = headers,
                Url = url,
                Method = MethodType.GET,
                ContentType = FormatType.JSON,
                Encoding = Encoding.UTF8.ToString()
            };

            HttpHandle http = new HttpHandle();
            HttpResponseDto response = http.HttpSendRequest(httpRequestDto);
            string message = response.ResponseMessage;

            Regex regex = new Regex("([\\\"](\\w+)[\\\"])([\\:]{1})(\\[\\])");
            while (regex.IsMatch(message))
            {
                string value = regex.Match(message).Value;
                Regex keyRegex = new Regex("([\\\"](\\w+)[\\\"])");
                string key = keyRegex.Match(value).Value;
                if(key!= "\"districts\"")
                {
                    message = message.Replace(value, string.Format("{0}:\"\"", key));
                }
                else
                {
                    message = message.Replace(value, string.Format("{0}:[_]", key));
                }
            }
            regex = new Regex("(\\[_\\])");
            while (regex.IsMatch(message))
            {
                string value = regex.Match(message).Value;
                message = message.Replace(value, "[]");
            }

            return JsonConvert.DeserializeObject<GeographyResponseDto>(message,
               new JsonSerializerSettings()
               {
                   ContractResolver = new DefaultContractResolver
                   {
                       NamingStrategy = new SnakeCaseNamingStrategy
                       {
                           ProcessDictionaryKeys = false
                       }
                   }
               });
        }
        public DirectionResponseDto GetDirection(DirectionRequestDto directionRequestDto)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            string url = string.Format("{0}?key={1}&origin={2}&destination={3}",
                AMapWebApiConfig.DirectionUrl,
                directionRequestDto.Key,
                string.Join(",", directionRequestDto.Origin),
                string.Join(",", directionRequestDto.Destination)
                );

            HttpRequestDto httpRequestDto = new HttpRequestDto()
            {
                Headers = headers,
                Url = url,
                Method = MethodType.GET,
                ContentType = FormatType.JSON,
                Encoding = Encoding.UTF8.ToString()
            };
            HttpHandle http = new HttpHandle();
            HttpResponseDto response = http.HttpSendRequest(httpRequestDto);

            return JsonConvert.DeserializeObject<DirectionResponseDto>(response.ResponseMessage,
                new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new SnakeCaseNamingStrategy
                        {
                            ProcessDictionaryKeys = false
                        }
                    }
                });
        }

        public DirectionResponseDto GetDirectionDriving(DirectionDrivingRequestDto directionDrivingRequestDto)
        {
            Dictionary<string, string> headers = new Dictionary<string, string>();
            string url = string.Format("{0}?key={1}&origin={2}&destination={3}&strategy={4}",
                AMapWebApiConfig.DirectionDrivingUrl,
                directionDrivingRequestDto.Key,
                string.Join(",", directionDrivingRequestDto.Origin),
                string.Join(",", directionDrivingRequestDto.Destination),
                2   //此策略 距离优先，不考虑路况，仅走距离最短的路线，但是可能存在穿越小路/小区的情况
                );

            HttpRequestDto httpRequestDto = new HttpRequestDto()
            {
                Headers = headers,
                Url = url,
                Method = MethodType.GET,
                ContentType = FormatType.JSON,
                Encoding = Encoding.UTF8.ToString()
            };
            HttpHandle http = new HttpHandle();
            HttpResponseDto response = http.HttpSendRequest(httpRequestDto);

            return JsonConvert.DeserializeObject<DirectionResponseDto>(response.ResponseMessage,
                new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new SnakeCaseNamingStrategy
                        {
                            ProcessDictionaryKeys = false
                        }
                    }
                });
        }
    }
}
